[C#] CSVファイルを利用したDataGridViewの作成方法
概要
Windowsフォームでは、DataGridViewが用意されており、表データを作成することが出来る。
この時、Csvファイルに表のフォーマットを記述しておくと、必要に応じてプログラム上から様々な表を作成することが出来る。(下図)
これにより様々なフォーマットのデータベースからの情報を、フォームに表示することが出来る。
ここでは、基本的な表の作成方法(行、列の追加)とCsvファイルの読み取り方に加え、表の選択行だけを抜き出して表示する方法について説明する。
目次
- CSVの読み取り方法と文字列の分割
- 列の追加方法
- 行の追加方法
- 選択行のデータ取得方法-Nullデータの扱い方-
- 選択行のデータ表示方法
- コードダウンロード
Csvの読み取り方法と文字列の分割
Csvファイルの読み取りには、StreamReaderを用いる。
StreamReaderのReadRowメソッドを使うとCsvファイルから1行分のデータを文字列として読み取る事が出来る。
読み取った文字列は、Splitメソッドを用い配列に格納する。この時引数に','を与えることで、カンマ毎に文字列を分割し格納することが出来る。(下記コード)
string[] value = bufColHeader.Split(',');//bufColHeaderにCSVから読み取った文字列が格納されている。
今回は、Csvファイルに、各列のヘッダー文字列と、各列の幅を以下の形式で記述して置いたものを、配列に格納している。
テスト1,テスト2,テスト3,テスト4,テスト5 //ヘッダーテキスト
50,100,150,200,250 //列幅
列の追加方法
列を追加するには、Columns.Addメソッドを用いる。引数は、列の名前と、ヘッダーテキストを与える必要がある。
今回は、列名とヘッダーテキストは同じ文字列とした。
また、ヘッダーテキストはCsvファイルから読み取った値を用いている。(下記コード)
string[] value = bufColHeader.Split(',');
for (int i = 0; i < value.Length; i++)
{
dataGridView1.Columns.Add(value[i], value[i]);
}
これにより読み取るCsvファイルを変更することで様々なフォーマットの表を作成する事が出来る。
行の追加方法
行を追加するには、Rows.Addを用いる。
ここで引数を用いてデータを同時にDataGridViewに追加する事が出来る。例えば、RowsAdd(1,2,3)のような記述の場合、表中に1,2,3が記入される。
今回は、Csvファイルから表のフォーマットを読み取ってからデータを記入するため、次のコードのように引数は与えていない。(フォーマットによって列の数が異なるため)
dataGridView1.Rows.Add();
また表の行番号は上から0,1,2・・・の順で割り当てられており、これと列番号を利用し表中のセルを指定しデータを記入する(下図)。
選択行のデータ取得方法-Nullデータの扱い方-
今回作成したフォームは、詳細ボタンを押すことで、別フォームに選択した行の内容を表示することが出来るようになっている。
そのためにまずは、プロパティ上で、MultiSelectとSelectionModeをそれぞれ、False,FullRowSelectにすることで、DataGridViewを複数行選択不可、行選択モードに設定する。(下図)
次に、選択行のデータを配列に格納していく。DataGridにはNullデータが格納されている場合もあるため、Convert.ToStringメソッドを用い、配列に格納していく。
こうする事で、Nullデータに対しても、例外が発生せず、空文字として取得できるようになる。(下記コード)
selectedData[i] = Convert.ToString(dataGridView1.SelectedRows[0].Cells[i].Value);//表のセル中のデータをselectedDataに格納している
後は配列と表のフォーマットデータをデータ表示用のフォームに渡すことで、表示を行う。
選択行のデータ表示方法
選択行のデータ表示用フォームでは、読み取ったデータと、表のフォーマットのデータを元に表示を行う。
今回は、ラベルに表のヘッダーテキスト、テキストボックスに読み取ったデータを表示するようにした。(下記コード)
for (int i = 0; i < items.Length; i++) { //表示項目の数だけ繰り返す
TextBox tb=new TextBox();
Label lbl=new Label();
tb.Location = new Point(80, i * 50);
tb.Name = items[i];
tb.Text = data[i];
lbl.Text = items[i];
lbl.Location=new Point(20, i * 50);
Controls.Add(tb);
Controls.Add((Label)lbl);
}
後は、実際に作るフォームアプリに合わせ、データ件数を表示する部分や数値の合計などを表示する部分などを作成すれば、選択行の詳細データ表示を作成する事が出来る。
フォーム作成用コード&exeファイル
CSV読み取りコード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MakeTable
{
public partial class Form1 : Form
{
string bufColHeader;
string bufColWidth;
int[,] rowData = new int[,] { { 1, 2, 3 }, { 5, 3, 4 } ,{ 0,8,56} }; //表に書き込む値。データベースなどから読み取った体で記述する。
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if (System.IO.File.Exists("表作成.csv"))
{
try
{
StreamReader reader = new StreamReader("表作成.csv");
bufColHeader = reader.ReadLine(); // 各列のHeadre:読み取る文字列⇒テスト1,テスト2,テスト3,テスト4,テスト5
bufColWidth = reader.ReadLine(); // 各列の幅:読み取る文字列⇒50,100,150,200,250
}
catch
{
MessageBox.Show("ファイルオープン失敗");
Application.Exit();
return;
}
}
else
{
MessageBox.Show("ファイルが見つかりません");
Application.Exit();
return;
}
int lengh;
// 列を追加
string[] value = bufColHeader.Split(',');
for (int i = 0; i < value.Length; i++)
{
dataGridView1.Columns.Add(value[i], value[i]);
}
// 列の幅を設定。
value = bufColWidth.Split(',');
lengh = dataGridView1.ColumnCount > value.Length ? value.Length : dataGridView1.ColumnCount; // 列数と設定項目数のうち少ない方
for (int i = 0; i < lengh; i++)
{
dataGridView1.Columns[i].Width = Convert.ToInt32(value[i]);
}
// 行を追加し値を書き込む
lengh = dataGridView1.ColumnCount < rowData.GetLength(1) ? dataGridView1.ColumnCount : rowData.GetLength(1); // 行数と記入するデータのうち少ない方
for (int j = 0; j < rowData.GetLength(0); j++)
{
dataGridView1.Rows.Add();
for (int i = 0; i < lengh; i++)
{
dataGridView1[i, j].Value = rowData[j, i];
}
}
}
private void detail_Click(object sender, EventArgs e)
{
//detail detaisF=new detail(bufColHeader.Split(','), Array.ConvertAll(rowData,x=>x.ToString()));
string[] selectedData = new string[dataGridView1.ColumnCount];
if (dataGridView1.SelectedRows.Count > 0)
{
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
selectedData[i] = Convert.ToString(dataGridView1.SelectedRows[0].Cells[i].Value);
}
detail detaisF = new detail(bufColHeader.Split(','), selectedData);
detaisF.ShowDialog();
}
}
}
}